import React, { useMemo, useRef, useState } from 'react';
import { LoadingOutlined, UploadOutlined } from '@ant-design/icons';
import { Flex, message, Upload, Button, Image } from 'antd';
import type { GetProp, UploadProps } from 'antd';
import { LibAppView } from "@/lib";
import lodash from 'lodash';
import { shouldSplitToUpload, UploadSplit } from "./UploadSplit";

type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
type UploadFile = Parameters<GetProp<UploadProps, 'onChange'>>[0]['file'];
interface IUploadProps {
    onChange?: (fileUrl: string, fileList: UploadFile[]) => void;
    fileList?: any[];
    showUploadList?: boolean;
    value?: string;
}

const getBase64 = (img: FileType, callback: (url: string) => void) => {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result as string));
  reader.readAsDataURL(img);
};

const VideoContentType = [
  "video/mp4", "video/x-msvideo", "video/webm","video/flv","video/avi","video/mov", "video/ogg",
  "audio/mp3","audio/mpeg","audio/wav","audio/mp4",
];
const UploadFile = LibAppView.withService<IUploadProps>()((props) => {
  const [loading, setLoading] = useState(false);
  const [imageUrl, setImageUrl] = useState<string>();
  const [ fileList, setFileList] = useState(props.fileList || []);
  const [ uploadPercent, setUploadPercent ] = useState("");
  const currentFile = useRef<any>({
    uid: null
  });
  const beforeUpload = (file: FileType) => {
    const isJpgOrPng = ["image/jpeg","image/png","image/gif", "image/bmp", "image/jpg"].includes(file.type);
    const isVideo = VideoContentType.includes(file.type);
    currentFile.current.uid = file.uid;
    if (!isJpgOrPng && !isVideo) {
      message.error('不支持的文件类型。');
    }
    const isLt2M = file.size / 1024 / 1024 < 900;
    const needsSplitUpload = shouldSplitToUpload(file);
    if (!isLt2M) {
      message.error('文件大小超出限制MB!');
      return;
    }
    if(needsSplitUpload) {
      const upload = new UploadSplit({
        file,
        blockSize: 1024 * 1024 * 2,
        service: props.withServiceApi,
        onFailed: () => {
          message.error('文件上传失败');
          setUploadPercent("");
        },
        onSuccess: (resp: any) => {
          const sourceUrl = resp?.data?.url || resp?.data?.id;
          setLoading(false);
          setUploadPercent("");
          typeof props.onChange === "function" && props.onChange(sourceUrl, [{
            response: resp,
            uid: resp?.data?.id,
            name: file.name,
            size: file.size,
            status: 'done'
          }]);
        },
        onProgress: ({ percent }: any) => {
          console.log(percent);
          setUploadPercent("/" + percent + "%");
        }
      });
      upload.start();
    }
    return (isJpgOrPng || isVideo) && isLt2M && !needsSplitUpload;
  };

  const handleChange: UploadProps['onChange'] = (info) => {

    if (info.file.status === 'uploading') {
      setLoading(true);
      return;
    }
    info.event
    if (info.file.status === 'done') {
      const sourceUrl = info.file.response?.data?.url || info.file.response?.data?.id;
      // Get this url from response in real world.
      getBase64(info.file.originFileObj as FileType, (url) => {
        setLoading(false);
        setImageUrl(url);
      });
      
      typeof props.onChange === "function" && props.onChange(sourceUrl, info.fileList);
    } else if(info.file.status === "removed") {
      typeof props.onChange === "function" && props.onChange("", info.fileList);
    }
  };

  const uploadButton = (
    <Button icon={loading ? <LoadingOutlined /> : <UploadOutlined />}>
      <span>上传</span>
    </Button>
  );
  const uploadAction = props.withServiceApi.getUrl("resource.upload") as string;
  const reviewUrl = props.withServiceApi.getUrl("resource.mediaUrl") as string;
  const imgUrl = useMemo(() => {
    if(props.value && props.value.length > 0) {
      return `${reviewUrl}/${props.value}`;
    }
  }, [ reviewUrl, props.value])

  return (
    <Flex gap="middle" wrap="wrap">
      <Upload
        name="file"
        // listType="picture-card"
        className="avatar-uploader"
        showUploadList={props.showUploadList}
        action={uploadAction}
        beforeUpload={beforeUpload}
        onChange={handleChange}
        // maxCount={1}
        // fileList={fileList}
        defaultFileList={fileList}
        withCredentials
      >
        {uploadButton}{uploadPercent}
        { fileList.length <= 0 && imgUrl && <Image style={{maxWidth: 100, display: "block"}} src={imgUrl} preview={false} />}
      </Upload>
    </Flex>
  );
});

export default UploadFile;